Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


RNS/Utilities/rnsh/process.py bebf211b01c5c08fcd4b1bcdb2cadc773e2b5127 (bebf211b) Text, 28.54 KB

T8b949e# Based on the original rnsh program by Aaron Heise (@acehoss)
T8b949e# https://github.com/acehoss/rnsh - MIT License - Copyright (c) 2023 Aaron Heise
T8b949e# This version of rnsh is included in RNS under the Reticulum License
T8b949e#
T8b949e# Reticulum License
T8b949e#
T8b949e# Copyright (c) 2016-2026 Mark Qvist
T8b949e#
T8b949e# Permission is hereby granted, free of charge, to any person obtaining a copy
T8b949e# of this software and associated documentation files (the "Software"), to deal
T8b949e# in the Software without restriction, including without limitation the rights
T8b949e# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
T8b949e# copies of the Software, and to permit persons to whom the Software is
T8b949e# furnished to do so, subject to the following conditions:
T8b949e#
T8b949e# - The Software shall not be used in any kind of system which includes amongst
T8b949e# its functions the ability to purposefully do harm to human beings.
T8b949e#
T8b949e# - The Software shall not be used, directly or indirectly, in the creation of
T8b949e# an artificial intelligence, machine learning or language model training
T8b949e# dataset, including but not limited to any use that contributes to the
T8b949e# training or development of such a model or algorithm.
T8b949e#
T8b949e# - The above copyright notice and this permission notice shall be included in
T8b949e# all copies or substantial portions of the Software.
T8b949e#
T8b949e# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
T8b949e# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
T8b949e# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
T8b949e# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
T8b949e# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
T8b949e# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
T8b949e# SOFTWARE.

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations
Tff7b72import T7ee787asyncio
Tff7b72import T7ee787contextlib
Tff7b72import T7ee787copy
Tff7b72import T7ee787errno
Tff7b72import T7ee787fcntl
Tff7b72import T7ee787functools
Tff7b72import T7ee787os
Tff7b72import T7ee787pty
Tff7b72import T7ee787select
Tff7b72import T7ee787signal
Tff7b72import T7ee787struct
Tff7b72import T7ee787sys
Tff7b72import T7ee787termios
Tff7b72import T7ee787threading
Tff7b72import T7ee787tty
Tff7b72import T7ee787types
Tff7b72import T7ee787typing
Tff7b72import T7ee787RNS

Tff7b72import T7ee787RNST7ee787.T7ee787UtilitiesT7ee787.T7ee787rnshT7ee787.T7ee787exception Tff7b72as T7ee787exception

Te6edf3CTRL_C Tff7b72= Ta5d6ff"Tffea00\x03Ta5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3CTRL_D Tff7b72= Ta5d6ff"Tffea00\x04Ta5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8fftty_add_reader_callbackTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4, Te6edf3callbackTb4b4b4: Tffa657callableTb4b4b4, Te6edf3loopTb4b4b4: Te6edf3asyncioTff7b72.Td2a8ffAbstractEventLoop Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
T8b949e"""
Add an async reader callback for a tty file descriptor.

Example usage:

def reader():
data = tty_read(fd)
# do something with data

tty_add_reader_callback(self._child_fd, reader, self._loop)

:param fd: file descriptor
:param callback: callback function
:param loop: asyncio event loop to which the reader should be added. If None, use the currently-running loop.
"""
Tff7b72if Te6edf3loop Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3loop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_running_loopTb4b4b4(Tb4b4b4)
Te6edf3loopTff7b72.Td2a8ffadd_readerTb4b4b4(Te6edf3fdTb4b4b4, Te6edf3callbackTb4b4b4)


Tff7b72def Td2a8fftty_readTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4) Tff7b72-Tff7b72> Tffa657bytesTb4b4b4:
T8b949e"""
Read available bytes from a tty file descriptor. When used in a callback added to a file descriptor using
tty_add_reader_callback(...), this function creates a solution for non-blocking reads from ttys.
:param fd: tty file descriptor
:return: bytes read
"""
Tff7b72if Te6edf3fd_is_closedTb4b4b4(Te6edf3fdTb4b4b4)Tb4b4b4:
Tff7b72raise Tf85149EOFError

Tff7b72tryTb4b4b4:
Te6edf3run Tff7b72= Tff7b72True
Te6edf3result Tff7b72= Tffa657bytearrayTb4b4b4(Tb4b4b4)
Tff7b72while Tff7b72not Te6edf3fd_is_closedTb4b4b4(Te6edf3fdTb4b4b4)Tb4b4b4:
Te6edf3readyTb4b4b4, Te6edf3_Tb4b4b4, Te6edf3_ Tff7b72= Te6edf3selectTff7b72.Td2a8ffselectTb4b4b4(Tb4b4b4[Te6edf3fdTb4b4b4]Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3readyTb4b4b4) Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72break
Tff7b72for Te6edf3f Tff7b72in Te6edf3readyTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Te6edf3osTff7b72.Td2a8ffreadTb4b4b4(Te6edf3fTb4b4b4, T79c0ff4096Tb4b4b4)
Tff7b72except Tf85149OSError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Te6edf3eTff7b72.Td2a8fferrno Tff7b72!= Te6edf3errnoTff7b72.Td2a8ffEIO Tff7b72and Te6edf3eTff7b72.Td2a8fferrno Tff7b72!= Te6edf3errnoTff7b72.Td2a8ffEWOULDBLOCKTb4b4b4:
Tff7b72raise
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72not Te6edf3dataTb4b4b4: T8b949e# EOF
Tff7b72if Te6edf3data Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3resultTff7b72.Td2a8ffextendTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72return Te6edf3result
Tff7b72elif Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Te6edf3result
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149EOFError
Tff7b72if Te6edf3data Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3resultTff7b72.Td2a8ffextendTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72return Te6edf3result
Tff7b72except Tf85149EOFErrorTb4b4b4: Tff7b72raise
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffTTY read error: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72def Td2a8fftty_read_pollTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4) Tff7b72-Tff7b72> Tffa657bytesTb4b4b4:
T8b949e"""
Read available bytes from a tty file descriptor. When used in a callback added to a file descriptor using
tty_add_reader_callback(...), this function creates a solution for non-blocking reads from ttys.
:param fd: tty file descriptor
:return: bytes read
"""
Tff7b72if Te6edf3fd_is_closedTb4b4b4(Te6edf3fdTb4b4b4)Tb4b4b4:
Tff7b72raise Tf85149EOFError

Te6edf3result Tff7b72= Tffa657bytearrayTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3flags Tff7b72= Te6edf3fcntlTff7b72.Td2a8fffcntlTb4b4b4(Te6edf3fdTb4b4b4, Te6edf3fcntlTff7b72.Td2a8ffF_GETFLTb4b4b4)
Te6edf3fcntlTff7b72.Td2a8fffcntlTb4b4b4(Te6edf3fdTb4b4b4, Te6edf3fcntlTff7b72.Td2a8ffF_SETFLTb4b4b4, Te6edf3flags Tff7b72| Te6edf3osTff7b72.Td2a8ffO_NONBLOCKTb4b4b4)
Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Te6edf3osTff7b72.Td2a8ffreadTb4b4b4(Te6edf3fdTb4b4b4, T79c0ff4096Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3dataTb4b4b4:
T8b949e# EOF
Tff7b72if Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Te6edf3result
Tff7b72raise Tf85149EOFError
Te6edf3resultTff7b72.Td2a8ffextendTb4b4b4(Te6edf3dataTb4b4b4)
T8b949e# continue loop to drain
Tff7b72except Tf85149OSError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Te6edf3eTff7b72.Td2a8fferrno Tff7b72in Tb4b4b4(Te6edf3errnoTff7b72.Td2a8ffEWOULDBLOCKTb4b4b4, Te6edf3errnoTff7b72.Td2a8ffEAGAINTb4b4b4)Tb4b4b4:
Tff7b72break
Tff7b72if Te6edf3eTff7b72.Td2a8fferrno Tff7b72== Te6edf3errnoTff7b72.Td2a8ffEIOTb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Te6edf3result
Tff7b72raise Tf85149EOFError
Tff7b72raise
Tff7b72except Tf85149EOFErrorTb4b4b4: Tff7b72raise
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffTTY read error: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Te6edf3result


Tff7b72def Td2a8fffd_is_closedTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""
Check if file descriptor is closed
:param fd: file descriptor
:return: True if file descriptor is closed
"""
Tff7b72tryTb4b4b4:
Te6edf3fcntlTff7b72.Td2a8fffcntlTb4b4b4(Te6edf3fdTb4b4b4, Te6edf3fcntlTff7b72.Td2a8ffF_GETFLTb4b4b4) Tff7b72< T79c0ff0
Tff7b72except Tf85149OSError Tff7b72as Te6edf3oseTb4b4b4:
Tff7b72return Te6edf3oseTff7b72.Td2a8fferrno Tff7b72== Te6edf3errnoTff7b72.Td2a8ffEBADF


Tff7b72def Td2a8fftty_unset_reader_callbacksTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4, Te6edf3loopTb4b4b4: Te6edf3asyncioTff7b72.Td2a8ffAbstractEventLoop Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
T8b949e"""
Remove async reader callbacks for file descriptor.
:param fd: file descriptor
:param loop: asyncio event loop from which to remove callbacks
"""
Tff7b72with Te6edf3exceptionTff7b72.Td2a8ffpermitTb4b4b4(Tf85149SystemExitTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3loop Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3loop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_running_loopTb4b4b4(Tb4b4b4)
Te6edf3loopTff7b72.Td2a8ffremove_readerTb4b4b4(Te6edf3fdTb4b4b4)


Tff7b72def Td2a8fftty_get_winsizeTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4) Tff7b72-Tff7b72> Tb4b4b4[Tffa657intTb4b4b4, Tffa657intTb4b4b4, Tffa657intTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4:
T8b949e"""
Ge the window size of a tty.
:param fd: file descriptor of tty
:return: (rows, cols, h_pixels, v_pixels)
"""
Te6edf3packed Tff7b72= Te6edf3fcntlTff7b72.Td2a8ffioctlTb4b4b4(Te6edf3fdTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTIOCGWINSZTb4b4b4, Te6edf3structTff7b72.Td2a8ffpackTb4b4b4(Ta5d6ff'Ta5d6ffHHHHTa5d6ff'Tb4b4b4, T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4)
Te6edf3rowsTb4b4b4, Te6edf3colsTb4b4b4, Te6edf3h_pixelsTb4b4b4, Te6edf3v_pixels Tff7b72= Te6edf3structTff7b72.Td2a8ffunpackTb4b4b4(Ta5d6ff'Ta5d6ffHHHHTa5d6ff'Tb4b4b4, Te6edf3packedTb4b4b4)
Tff7b72return Te6edf3rowsTb4b4b4, Te6edf3colsTb4b4b4, Te6edf3h_pixelsTb4b4b4, Te6edf3v_pixels


Tff7b72def Td2a8fftty_set_winsizeTb4b4b4(Te6edf3fdTb4b4b4: Tffa657intTb4b4b4, Te6edf3rowsTb4b4b4: Tffa657intTb4b4b4, Te6edf3colsTb4b4b4: Tffa657intTb4b4b4, Te6edf3h_pixelsTb4b4b4: Tffa657intTb4b4b4, Te6edf3v_pixelsTb4b4b4: Tffa657intTb4b4b4)Tb4b4b4:
T8b949e"""
Set the window size on a tty.
:param fd: file descriptor of tty
:param rows: number of visible rows
:param cols: number of visible columns
:param h_pixels: number of visible horizontal pixels
:param v_pixels: number of visible vertical pixels
"""
Tff7b72if Te6edf3fd Tff7b72< T79c0ff0Tb4b4b4:
Tff7b72return
Te6edf3packed Tff7b72= Te6edf3structTff7b72.Td2a8ffpackTb4b4b4(Ta5d6ff'Ta5d6ffHHHHTa5d6ff'Tb4b4b4, Te6edf3rowsTb4b4b4, Te6edf3colsTb4b4b4, Te6edf3h_pixelsTb4b4b4, Te6edf3v_pixelsTb4b4b4)
Te6edf3fcntlTff7b72.Td2a8ffioctlTb4b4b4(Te6edf3fdTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTIOCSWINSZTb4b4b4, Te6edf3packedTb4b4b4)


Tff7b72def Td2a8ffprocess_existsTb4b4b4(Te6edf3pidTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""
Check For the existence of a unix pid.
:param pid: process id to check
:return: True if process exists
"""
Tff7b72tryTb4b4b4:
Te6edf3osTff7b72.Td2a8ffkillTb4b4b4(Te6edf3pidTb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72True


Tff7b72class T56d364TTYRestorerTb4b4b4(Te6edf3contextlibTff7b72.Td2a8ffAbstractContextManagerTb4b4b4)Tb4b4b4:
T8b949e# Indexes of flags within the attrs array
Te6edf3ATTR_IDX_IFLAG Tff7b72= T79c0ff0
Te6edf3ATTR_IDX_OFLAG Tff7b72= T79c0ff1
Te6edf3ATTR_IDX_CFLAG Tff7b72= T79c0ff2
Te6edf3ATTR_IDX_LFLAG Tff7b72= T79c0ff4
Te6edf3ATTR_IDX_CC Tff7b72= T79c0ff5

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3fdTb4b4b4: Tffa657intTb4b4b4, Te6edf3suppress_logsTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
T8b949e"""
Saves termios attributes for a tty for later restoration.

The attributes are an array of values with the following meanings.

tcflag_t c_iflag; /* input modes */
tcflag_t c_oflag; /* output modes */
tcflag_t c_cflag; /* control modes */
tcflag_t c_lflag; /* local modes */
cc_t c_cc[NCCS]; /* special characters */

:param fd: file descriptor of tty
"""
Tff7b72selfTff7b72.Td2a8ff_fd Tff7b72= Te6edf3fd
Tff7b72selfTff7b72.Td2a8ff_tattr Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_suppress_logs Tff7b72= Te6edf3suppress_logs
Tff7b72selfTff7b72.Td2a8ff_tattr Tff7b72= Tff7b72selfTff7b72.Td2a8ffcurrent_attrTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_tattr Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ff_suppress_logsTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCould not get attrs for fd Tffd700{Te6edf3fdTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffrawTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
Set raw mode on tty
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_fd Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Te6edf3termiosTff7b72.Td2a8fferrorTb4b4b4)Tb4b4b4:
Te6edf3ttyTff7b72.Td2a8ffsetrawTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_fdTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTCSANOWTb4b4b4)

Tff7b72def Td2a8fforiginal_attrTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tb4b4b4[Tffa657anyTb4b4b4]Tb4b4b4:
Tff7b72return Te6edf3copyTff7b72.Td2a8ffdeepcopyTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_tattrTb4b4b4)

Tff7b72def Td2a8ffcurrent_attrTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tb4b4b4[Tffa657anyTb4b4b4]Tb4b4b4:
T8b949e"""
Get the current termios attributes for the wrapped fd.
:return: attribute array
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_fd Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Te6edf3termiosTff7b72.Td2a8fferrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3copyTff7b72.Td2a8ffdeepcopyTb4b4b4(Te6edf3termiosTff7b72.Td2a8fftcgetattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_fdTb4b4b4)Tb4b4b4)
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffset_attrTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3attrTb4b4b4: Tb4b4b4[Tffa657anyTb4b4b4]Tb4b4b4, Te6edf3whenTb4b4b4: Tffa657int Tff7b72= Te6edf3termiosTff7b72.Td2a8ffTCSADRAINTb4b4b4)Tb4b4b4:
T8b949e"""
Set termios attributes
:param attr: attribute list to set
:param when: when attributes should be applied (termios.TCSANOW, termios.TCSADRAIN, termios.TCSAFLUSH)
"""
Tff7b72if Tff7b72not Te6edf3attr Tff7b72or Tff7b72selfTff7b72.Td2a8ff_fd Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return

Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Te6edf3termiosTff7b72.Td2a8fferrorTb4b4b4)Tb4b4b4:
Te6edf3termiosTff7b72.Td2a8fftcsetattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_fdTb4b4b4, Te6edf3whenTb4b4b4, Te6edf3attrTb4b4b4)

Tff7b72def Td2a8ffisattyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3osTff7b72.Td2a8ffisattyTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_fdTb4b4b4) Tff7b72if Tff7b72selfTff7b72.Td2a8ff_fd Tff7b72is Tff7b72not Tff7b72None Tff7b72else Tff7b72None

Tff7b72def Td2a8ffrestoreTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
Restore termios settings to state captured in constructor.
"""
Tff7b72selfTff7b72.Td2a8ffset_attrTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_tattrTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTCSADRAINTb4b4b4)

Tff7b72def Tff7b72__exit__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3__exc_typeTb4b4b4: Te6edf3typingTff7b72.Td2a8ffTypeTb4b4b4[Tf85149BaseExceptionTb4b4b4]Tb4b4b4, Te6edf3__exc_valueTb4b4b4: Tf85149BaseExceptionTb4b4b4,
Te6edf3__tracebackTb4b4b4: Te6edf3typesTff7b72.Td2a8ffTracebackTypeTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrestoreTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72False T8b949e#__exc_type is not None and issubclass(__exc_type, termios.error)


Tff7b72def Td2a8ff_task_from_eventTb4b4b4(Te6edf3evtTb4b4b4: Te6edf3asyncioTff7b72.Td2a8ffEventTb4b4b4, Te6edf3loopTb4b4b4: Te6edf3asyncioTff7b72.Td2a8ffAbstractEventLoop Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3loopTb4b4b4:
Te6edf3loop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_running_loopTb4b4b4(Tb4b4b4)

T8b949e#TODO: this is hacky
Tff7b72async Tff7b72def Td2a8ffwaitTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72not Te6edf3evtTff7b72.Td2a8ffis_setTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)
Tff7b72return Tff7b72True

Tff7b72return Te6edf3loopTff7b72.Td2a8ffcreate_taskTb4b4b4(Te6edf3waitTb4b4b4(Tb4b4b4)Tb4b4b4)


Tff7b72class T56d364AggregateExceptionTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3inner_exceptionsTb4b4b4: Tb4b4b4[Tf85149ExceptionTb4b4b4]Tb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffinner_exceptions Tff7b72= Te6edf3inner_exceptions

Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffMultiple exceptions encountered: Tffea00\nTffea00\nTa5d6ff" Tff7b72+ Ta5d6ff"Tffea00\nTffea00\nTa5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Tffa657mapTb4b4b4(Tff7b72lambda Te6edf3eTb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffinner_exceptionsTb4b4b4)Tb4b4b4)


Tff7b72async Tff7b72def Td2a8ffevent_wait_anyTb4b4b4(Te6edf3evtsTb4b4b4: Tb4b4b4[Te6edf3asyncioTff7b72.Td2a8ffEventTb4b4b4]Tb4b4b4, Te6edf3timeoutTb4b4b4: Tffa657float Tff7b72= Tff7b72NoneTb4b4b4) Tff7b72-Tff7b72> Tb4b4b4(Tffa657anyTb4b4b4, Tffa657anyTb4b4b4)Tb4b4b4:
Te6edf3tasks Tff7b72= Tffa657listTb4b4b4(Tffa657mapTb4b4b4(Tff7b72lambda Te6edf3evtTb4b4b4: Tb4b4b4(Te6edf3evtTb4b4b4, Te6edf3_task_from_eventTb4b4b4(Te6edf3evtTb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3evtsTb4b4b4)Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3finishedTb4b4b4, Te6edf3unfinished Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffwaitTb4b4b4(Tffa657mapTb4b4b4(Tff7b72lambda Te6edf3tTb4b4b4: Te6edf3tTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Te6edf3tasksTb4b4b4)Tb4b4b4,
Te6edf3timeoutTff7b72=Te6edf3timeoutTb4b4b4,
Te6edf3return_whenTff7b72=Te6edf3asyncioTff7b72.Td2a8ffFIRST_COMPLETEDTb4b4b4)

Tff7b72if Tffa657lenTb4b4b4(Te6edf3unfinishedTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72for Te6edf3task Tff7b72in Te6edf3unfinishedTb4b4b4:
Te6edf3taskTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffwaitTb4b4b4(Te6edf3unfinishedTb4b4b4)

Te6edf3exceptions Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72for Te6edf3f Tff7b72in Te6edf3finishedTb4b4b4:
Te6edf3ex Tff7b72= Te6edf3fTff7b72.Td2a8ffexceptionTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3ex Tff7b72and Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3exTb4b4b4, Te6edf3asyncioTff7b72.Td2a8ffCancelledErrorTb4b4b4) Tff7b72and Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3exTb4b4b4, Tf85149TimeoutErrorTb4b4b4)Tb4b4b4:
Te6edf3exceptionsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3exTb4b4b4)

Tff7b72if Tffa657lenTb4b4b4(Te6edf3exceptionsTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72raise Te6edf3AggregateExceptionTb4b4b4(Te6edf3exceptionsTb4b4b4)

Tff7b72return Tffa657nextTb4b4b4(Tffa657mapTb4b4b4(Tff7b72lambda Te6edf3tTb4b4b4: Tffa657nextTb4b4b4(Tffa657mapTb4b4b4(Tff7b72lambda Te6edf3ttTb4b4b4: Te6edf3ttTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3tasksTb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3finishedTb4b4b4)Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72finallyTb4b4b4:
Te6edf3unfinished Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3task Tff7b72in Tffa657mapTb4b4b4(Tff7b72lambda Te6edf3tTb4b4b4: Te6edf3tTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Te6edf3tasksTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3taskTff7b72.Td2a8ffdoneTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3taskTff7b72.Td2a8ffcancelledTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3taskTff7b72.Td2a8ffexceptionTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3taskTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Te6edf3unfinishedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3taskTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3unfinishedTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffwaitTb4b4b4(Te6edf3unfinishedTb4b4b4)


Tff7b72async Tff7b72def Td2a8ffevent_waitTb4b4b4(Te6edf3evtTb4b4b4: Te6edf3asyncioTff7b72.Td2a8ffEventTb4b4b4, Te6edf3timeoutTb4b4b4: Tffa657floatTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""
Wait for event to be set, or timeout to expire.
:param evt: asyncio.Event to wait on
:param timeout: maximum number of seconds to wait.
:return: True if event was set, False if timeout expired
"""
Tff7b72await Te6edf3event_wait_anyTb4b4b4(Tb4b4b4[Te6edf3evtTb4b4b4]Tb4b4b4, Te6edf3timeoutTff7b72=Te6edf3timeoutTb4b4b4)
Tff7b72return Te6edf3evtTff7b72.Td2a8ffis_setTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ff_launch_childTb4b4b4(Te6edf3cmd_lineTb4b4b4: Tffa657listTb4b4b4[Tffa657strTb4b4b4]Tb4b4b4, Te6edf3envTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657strTb4b4b4]Tb4b4b4, Te6edf3stdin_is_pipeTb4b4b4: Tffa657boolTb4b4b4, Te6edf3stdout_is_pipeTb4b4b4: Tffa657boolTb4b4b4,
Te6edf3stderr_is_pipeTb4b4b4: Tffa657boolTb4b4b4) Tff7b72-Tff7b72> Tffa657tupleTb4b4b4[Tffa657intTb4b4b4, Tffa657intTb4b4b4, Tffa657intTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4:
T8b949e# Set up PTY and/or pipes
Te6edf3child_fd Tff7b72= Te6edf3parent_fd Tff7b72= Tff7b72None
Tff7b72if Tff7b72not Tb4b4b4(Te6edf3stdin_is_pipe Tff7b72and Te6edf3stdout_is_pipe Tff7b72and Te6edf3stderr_is_pipeTb4b4b4)Tb4b4b4:
Te6edf3parent_fdTb4b4b4, Te6edf3child_fd Tff7b72= Te6edf3ptyTff7b72.Td2a8ffopenptyTb4b4b4(Tb4b4b4)
Te6edf3child_stdinTb4b4b4, Te6edf3parent_stdin Tff7b72= Tb4b4b4(Te6edf3osTff7b72.Td2a8ffpipeTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3stdin_is_pipe Tff7b72else Tb4b4b4(Te6edf3child_fdTb4b4b4, Te6edf3parent_fdTb4b4b4)Tb4b4b4)
Te6edf3parent_stdoutTb4b4b4, Te6edf3child_stdout Tff7b72= Tb4b4b4(Te6edf3osTff7b72.Td2a8ffpipeTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3stdout_is_pipe Tff7b72else Tb4b4b4(Te6edf3parent_fdTb4b4b4, Te6edf3child_fdTb4b4b4)Tb4b4b4)
Te6edf3parent_stderrTb4b4b4, Te6edf3child_stderr Tff7b72= Tb4b4b4(Te6edf3osTff7b72.Td2a8ffpipeTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3stderr_is_pipe Tff7b72else Tb4b4b4(Te6edf3parent_fdTb4b4b4, Te6edf3child_fdTb4b4b4)Tb4b4b4)

T8b949e# Fork
Te6edf3pid Tff7b72= Te6edf3osTff7b72.Td2a8ffforkTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3pid Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72tryTb4b4b4:
T8b949e# We are in the child process, so close all open sockets and pipes except for the PTY and/or pipes
Te6edf3max_fd Tff7b72= Te6edf3osTff7b72.Td2a8ffsysconfTb4b4b4(Ta5d6ff"Ta5d6ffSC_OPEN_MAXTa5d6ff"Tb4b4b4)
Tff7b72for Te6edf3fd Tff7b72in Tffa657rangeTb4b4b4(T79c0ff3Tb4b4b4, Te6edf3max_fdTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3fd Tff7b72not Tff7b72in Tb4b4b4(Te6edf3child_stdinTb4b4b4, Te6edf3child_stdoutTb4b4b4, Te6edf3child_stderrTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3fdTb4b4b4)
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72pass

T8b949e# Set up PTY and/or pipes
Te6edf3osTff7b72.Td2a8ffdup2Tb4b4b4(Te6edf3child_stdinTb4b4b4, T79c0ff0Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffdup2Tb4b4b4(Te6edf3child_stdoutTb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffdup2Tb4b4b4(Te6edf3child_stderrTb4b4b4, T79c0ff2Tb4b4b4)
T8b949e# Make PTY controlling if necessary so that CTRL_C/CTRL_D behave as expected
Tff7b72if Te6edf3child_fd Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3osTff7b72.Td2a8ffsetsidTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3tty_fd Tff7b72= T79c0ff0 Tff7b72if Tff7b72not Te6edf3stdin_is_pipe Tff7b72else Tb4b4b4(T79c0ff1 Tff7b72if Tff7b72not Te6edf3stdout_is_pipe Tff7b72else T79c0ff2Tb4b4b4)
T8b949e# Set controlling TTY for this session
Te6edf3fcntlTff7b72.Td2a8ffioctlTb4b4b4(Te6edf3tty_fdTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTIOCSCTTYTb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
T8b949e# Ensure the child is the foreground process group for the TTY
Tff7b72tryTb4b4b4:
Te6edf3osTff7b72.Td2a8ffsetpgidTb4b4b4(T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4)
Te6edf3pgid Tff7b72= Te6edf3osTff7b72.Td2a8ffgetpgrpTb4b4b4(Tb4b4b4)
Tff7b72import T7ee787struct Tff7b72as T7ee787_struct
Te6edf3fcntlTff7b72.Td2a8ffioctlTb4b4b4(Te6edf3tty_fdTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTIOCSPGRPTb4b4b4, Te6edf3_structTff7b72.Td2a8ffpackTb4b4b4(Ta5d6ff'Ta5d6ffiTa5d6ff'Tb4b4b4, Te6edf3pgidTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
T8b949e# Ensure canonical input with signals and local echo enabled
Tff7b72tryTb4b4b4:
Te6edf3tty_fd Tff7b72= T79c0ff0 Tff7b72if Tff7b72not Te6edf3stdin_is_pipe Tff7b72else Tb4b4b4(T79c0ff1 Tff7b72if Tff7b72not Te6edf3stdout_is_pipe Tff7b72else T79c0ff2Tb4b4b4)
Te6edf3attrs Tff7b72= Te6edf3termiosTff7b72.Td2a8fftcgetattrTb4b4b4(Te6edf3tty_fdTb4b4b4)
Te6edf3lflag Tff7b72= Te6edf3attrsTb4b4b4[T79c0ff3Tb4b4b4]
Te6edf3lflag Tff7b72|Tff7b72= Te6edf3termiosTff7b72.Td2a8ffICANON Tff7b72| Te6edf3termiosTff7b72.Td2a8ffISIG Tff7b72| Te6edf3termiosTff7b72.Td2a8ffECHO
Te6edf3attrsTb4b4b4[T79c0ff3Tb4b4b4] Tff7b72= Te6edf3lflag
Te6edf3termiosTff7b72.Td2a8fftcsetattrTb4b4b4(Te6edf3tty_fdTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTCSANOWTb4b4b4, Te6edf3attrsTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

T8b949e# Execute the command
Te6edf3osTff7b72.Td2a8ffexecvpeTb4b4b4(Te6edf3cmd_lineTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3cmd_lineTb4b4b4, Te6edf3envTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3errTb4b4b4:
Te6edf3exc_typeTb4b4b4, Te6edf3exc_objTb4b4b4, Te6edf3exc_tb Tff7b72= Te6edf3sysTff7b72.Td2a8ffexc_infoTb4b4b4(Tb4b4b4)
Te6edf3fname Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffsplitTb4b4b4(Te6edf3exc_tbTff7b72.Td2a8fftb_frameTff7b72.Td2a8fff_codeTff7b72.Td2a8ffco_filenameTb4b4b4)Tb4b4b4[T79c0ff1Tb4b4b4]
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffUnable to start Tffd700{Te6edf3cmd_lineTb4b4b4[T79c0ff0Tb4b4b4]Tffd700}Ta5d6ff: Tffd700{Te6edf3errTffd700}Ta5d6ff (Tffd700{Te6edf3fnameTffd700}Ta5d6ff:Tffd700{Te6edf3exc_tbTff7b72.Td2a8fftb_linenoTffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4)
Te6edf3sysTff7b72.Td2a8ffstdoutTff7b72.Td2a8ffflushTb4b4b4(Tb4b4b4)
T8b949e# don't let any other modules get in our way, do an immediate silent exit.
Te6edf3osTff7b72.Td2a8ff_exitTb4b4b4(T79c0ff255Tb4b4b4)

Tff7b72elseTb4b4b4:
T8b949e# We are in the parent process, so close the child-side of the PTY and/or pipes
Tff7b72if Te6edf3child_fd Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3child_fdTb4b4b4)
Tff7b72if Te6edf3child_stdin Tff7b72!= Te6edf3child_fdTb4b4b4:
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3child_stdinTb4b4b4)
Tff7b72if Te6edf3child_stdout Tff7b72!= Te6edf3child_fdTb4b4b4:
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3child_stdoutTb4b4b4)
Tff7b72if Te6edf3child_stderr Tff7b72!= Te6edf3child_fdTb4b4b4:
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3child_stderrTb4b4b4)
T8b949e# # Close the write end of the pipe if a pipe is used for standard input
T8b949e# if not stdin_is_pipe:
T8b949e# os.close(parent_stdin)
T8b949e# Return the child PID and the file descriptors for the PTY and/or pipes
Tff7b72return Te6edf3pidTb4b4b4, Te6edf3parent_stdinTb4b4b4, Te6edf3parent_stdoutTb4b4b4, Te6edf3parent_stderr


Tff7b72class T56d364CallbackSubprocessTb4b4b4:
T8b949e# time between checks of child process
Te6edf3PROCESS_POLL_TIMETb4b4b4: Tffa657float Tff7b72= T79c0ff0.1
T8b949e# Close pipes soon after process exit to avoid scheduling on closed event loops
Te6edf3PROCESS_PIPE_TIMETb4b4b4: Tffa657int Tff7b72= T79c0ff1

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3argvTb4b4b4: Tb4b4b4[Tffa657strTb4b4b4]Tb4b4b4, Te6edf3envTb4b4b4: Tffa657dictTb4b4b4, Te6edf3loopTb4b4b4: Te6edf3asyncioTff7b72.Td2a8ffAbstractEventLoopTb4b4b4, Te6edf3stdout_callbackTb4b4b4: Tffa657callableTb4b4b4,
Te6edf3stderr_callbackTb4b4b4: Tffa657callableTb4b4b4, Te6edf3terminated_callbackTb4b4b4: Tffa657callableTb4b4b4, Te6edf3stdin_is_pipeTb4b4b4: Tffa657boolTb4b4b4, Te6edf3stdout_is_pipeTb4b4b4: Tffa657boolTb4b4b4,
Te6edf3stderr_is_pipeTb4b4b4: Tffa657boolTb4b4b4)Tb4b4b4:
T8b949e"""
Fork a child process and generate callbacks with output from the process.
:param argv: the command line, tokenized. The first element must be the absolute path to an executable file.
:param env: environment variables to override
:param loop: the asyncio event loop to use
:param stdout_callback: callback for data, e.g. def callback(data:bytes) -> None
:param terminated_callback: callback for termination/return code, e.g. def callback(return_code:int) -> None
"""
Tff7b72assert Te6edf3loop Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4, Ta5d6ff"Ta5d6ffloop should not be NoneTa5d6ff"
Tff7b72assert Te6edf3stdout_callback Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4, Ta5d6ff"Ta5d6ffstdout_callback should not be NoneTa5d6ff"
Tff7b72assert Te6edf3terminated_callback Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4, Ta5d6ff"Ta5d6ffterminated_callback should not be NoneTa5d6ff"

Tff7b72selfTff7b72.Td2a8ff_commandTb4b4b4: Tb4b4b4[Tffa657strTb4b4b4] Tff7b72= Te6edf3argv
Tff7b72selfTff7b72.Td2a8ff_env Tff7b72= Te6edf3env Tff7b72or Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ff_loop Tff7b72= Te6edf3loop
Tff7b72selfTff7b72.Td2a8ff_stdout_cb Tff7b72= Te6edf3stdout_callback
Tff7b72selfTff7b72.Td2a8ff_stderr_cb Tff7b72= Te6edf3stderr_callback
Tff7b72selfTff7b72.Td2a8ff_terminated_cb Tff7b72= Te6edf3terminated_callback
Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4: Tffa657int Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_child_stdinTb4b4b4: Tffa657int Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4: Tffa657int Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_child_stderrTb4b4b4: Tffa657int Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_return_codeTb4b4b4: Tffa657int Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_stdout_eofTb4b4b4: Tffa657bool Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_stderr_eofTb4b4b4: Tffa657bool Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_stdin_is_pipe Tff7b72= Te6edf3stdin_is_pipe
Tff7b72selfTff7b72.Td2a8ff_stdout_is_pipe Tff7b72= Te6edf3stdout_is_pipe
Tff7b72selfTff7b72.Td2a8ff_stderr_is_pipe Tff7b72= Te6edf3stderr_is_pipe
Tff7b72selfTff7b72.Td2a8ff_at_line_startTb4b4b4: Tffa657bool Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_tty_line_bufferTb4b4b4: Tffa657bytearray Tff7b72= Tffa657bytearrayTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_ensure_pipes_closedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3stdin Tff7b72= Tff7b72selfTff7b72.Td2a8ff_child_stdin
Te6edf3stdout Tff7b72= Tff7b72selfTff7b72.Td2a8ff_child_stdout
Te6edf3stderr Tff7b72= Tff7b72selfTff7b72.Td2a8ff_child_stderr
Te6edf3fds Tff7b72= Tffa657setTb4b4b4(Tffa657filterTb4b4b4(Tff7b72lambda Te6edf3xTb4b4b4: Te6edf3x Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4, Tffa657listTb4b4b4(Tb4b4b4{Te6edf3stdinTb4b4b4, Te6edf3stdoutTb4b4b4, Te6edf3stderrTb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffQueuing close of pipes for ended process (fds: Tffd700{Te6edf3fdsTffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffensure_pipes_closed_innerTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffEnsuring pipes are closed (fds: Tffd700{Te6edf3fdsTffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72for Te6edf3fd Tff7b72in Te6edf3fdsTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffClosing fd Tffd700{Te6edf3fdTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149OSErrorTb4b4b4)Tb4b4b4: Te6edf3tty_unset_reader_callbacksTb4b4b4(Te6edf3fdTb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149OSErrorTb4b4b4)Tb4b4b4: Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Te6edf3fdTb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_child_stdin Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_child_stdout Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_child_stderr Tff7b72= Tff7b72None

T8b949e# Avoid scheduling on a closed loop
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffis_closedTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3ensure_pipes_closed_innerTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(Te6edf3CallbackSubprocessTff7b72.Td2a8ffPROCESS_PIPE_TIMETb4b4b4, Te6edf3ensure_pipes_closed_innerTb4b4b4)

Tff7b72def Td2a8ffterminateTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3kill_delayTb4b4b4: Tffa657float Tff7b72= T79c0ff1.0Tb4b4b4)Tb4b4b4:
T8b949e"""
Terminate child process if running
:param kill_delay: if after kill_delay seconds the child process has not exited, escalate to SIGHUP and SIGKILL
"""

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffterminate()Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4: Tff7b72return

Tff7b72with Te6edf3exceptionTff7b72.Td2a8ffpermitTb4b4b4(Tf85149SystemExitTb4b4b4)Tb4b4b4: Te6edf3osTff7b72.Td2a8ffkillTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4, Te6edf3signalTff7b72.Td2a8ffSIGTERMTb4b4b4)

Tff7b72def Td2a8ffkillTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3process_existsTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffkill()Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72with Te6edf3exceptionTff7b72.Td2a8ffpermitTb4b4b4(Tf85149SystemExitTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffkillTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4, Te6edf3signalTff7b72.Td2a8ffSIGHUPTb4b4b4)
Te6edf3osTff7b72.Td2a8ffkillTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4, Te6edf3signalTff7b72.Td2a8ffSIGKILLTb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(Te6edf3kill_delayTb4b4b4, Te6edf3killTb4b4b4)

Tff7b72def Td2a8ffwaitTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffwait()Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149OSErrorTb4b4b4)Tb4b4b4: Te6edf3osTff7b72.Td2a8ffwaitpidTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_ensure_pipes_closedTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffwait() finishTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)

Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3waitTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffclose_stdinTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffcloseTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdinTb4b4b4)
T8b949e# Encourage prompt shutdown if child lingers after stdin close
Tff7b72def Td2a8ff_ensure_terminateTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffterminateTb4b4b4(Te6edf3kill_delayTff7b72=T79c0ff0.2Tb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffis_closedTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(T79c0ff0.05Tb4b4b4, Te6edf3_ensure_terminateTb4b4b4)

Tf0883e@property
Tff7b72def Td2a8ffstartedTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""
:return: True if child process has been started
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_pid Tff7b72is Tff7b72not Tff7b72None

Tf0883e@property
Tff7b72def Td2a8ffrunningTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""
:return: True if child process is still running
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_pid Tff7b72is Tff7b72not Tff7b72None Tff7b72and Te6edf3process_existsTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4)

Tff7b72def Td2a8ffwriteTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4:
T8b949e"""
Write bytes to the stdin of the child process.
:param data: bytes to write
"""

Te6edf3osTff7b72.Td2a8ffwriteTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdinTb4b4b4, Te6edf3dataTb4b4b4)

T8b949e# TODO: Check what this is actually supposed to solve.
T8b949e#
T8b949e# For pipe-in + TTY-out, echo should be visible immediately
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_stdin_is_pipe Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ff_stdout_is_pipe Tff7b72and Tff7b72selfTff7b72.Td2a8ff_stdout_cb Tff7b72is Tff7b72not Tff7b72None Tff7b72and Te6edf3data Tff7b72not Tff7b72in Tb4b4b4(Te6edf3CTRL_CTb4b4b4, Te6edf3CTRL_DTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8ff_stdout_cbTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4: Tff7b72pass

Tff7b72def Td2a8ffset_winsizeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rTb4b4b4: Tffa657intTb4b4b4, Te6edf3cTb4b4b4: Tffa657intTb4b4b4, Te6edf3hTb4b4b4: Tffa657intTb4b4b4, Te6edf3vTb4b4b4: Tffa657intTb4b4b4)Tb4b4b4:
T8b949e"""
Set the window size on the tty of the child process.
:param r: rows visible
:param c: columns visible
:param h: horizontal pixels visible
:param v: vertical pixels visible
:return:
"""
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffset_winsize(Tffd700{Te6edf3rTffd700}Ta5d6ff,Tffd700{Te6edf3cTffd700}Ta5d6ff,Tffd700{Te6edf3hTffd700}Ta5d6ff,Tffd700{Te6edf3vTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3tty_set_winsizeTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4, Te6edf3rTb4b4b4, Te6edf3cTb4b4b4, Te6edf3hTb4b4b4, Te6edf3vTb4b4b4)

Tff7b72def Td2a8ffcopy_winsizeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3fromfdTb4b4b4: Tffa657intTb4b4b4)Tb4b4b4:
T8b949e"""
Copy window size from one tty to another.
:param fromfd: source tty file descriptor
"""
Te6edf3rTb4b4b4, Te6edf3cTb4b4b4, Te6edf3hTb4b4b4, Te6edf3v Tff7b72= Te6edf3tty_get_winsizeTb4b4b4(Te6edf3fromfdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffset_winsizeTb4b4b4(Te6edf3rTb4b4b4, Te6edf3cTb4b4b4, Te6edf3hTb4b4b4, Te6edf3vTb4b4b4)

Tff7b72def Td2a8fftcsetattrTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3whenTb4b4b4: Tffa657intTb4b4b4, Te6edf3attrTb4b4b4: Tffa657listTb4b4b4[Tffa657anyTb4b4b4]Tb4b4b4)Tb4b4b4: T8b949e# actual type is list[int | list[int | bytes]]
T8b949e"""
Set tty attributes.
:param when: when to apply change: termios.TCSANOW or termios.TCSADRAIN or termios.TCSAFLUSH
:param attr: attributes to set
"""
Te6edf3termiosTff7b72.Td2a8fftcsetattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdinTb4b4b4, Te6edf3whenTb4b4b4, Te6edf3attrTb4b4b4)

Tff7b72def Td2a8fftcgetattrTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657anyTb4b4b4]Tb4b4b4: T8b949e# actual type is list[int | list[int | bytes]]
T8b949e"""
Get tty attributes.
:return: tty attributes value
"""
Tff7b72return Te6edf3termiosTff7b72.Td2a8fftcgetattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4)

Tff7b72def Td2a8ffttysetrawTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3ttyTff7b72.Td2a8ffsetrawTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4, Te6edf3termiosTff7b72.Td2a8ffTCSADRAINTb4b4b4)

Tff7b72def Td2a8ffstartTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
Start the child process.
"""
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffstart()Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)

T8b949e# # Using the parent environment seems to do some weird stuff, at least on macOS
T8b949e# parentenv = os.environ.copy()
T8b949e# env = {"HOME": parentenv["HOME"],
T8b949e# "PATH": parentenv["PATH"],
T8b949e# "TERM": self._term if self._term is not None else parentenv.get("TERM", "xterm"),
T8b949e# "LANG": parentenv.get("LANG"),
T8b949e# "SHELL": self._command[0]}

Te6edf3env Tff7b72= Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffcopyTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3key Tff7b72in Tff7b72selfTff7b72.Td2a8ff_envTb4b4b4:
Te6edf3envTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72= Tff7b72selfTff7b72.Td2a8ff_envTb4b4b4[Te6edf3keyTb4b4b4]

Te6edf3program Tff7b72= Tff7b72selfTff7b72.Td2a8ff_commandTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72assert Tffa657isinstanceTb4b4b4(Te6edf3programTb4b4b4, Tffa657strTb4b4b4)

T8b949e# match = re.search("^/bin/(.*sh)$", program)
T8b949e# if match:
T8b949e# self._command[0] = "-" + match.group(1)
T8b949e# env["SHELL"] = program
T8b949e# self._log.debug(f"set login shell {self._command}")

Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4, \
Tff7b72selfTff7b72.Td2a8ff_child_stdinTb4b4b4, \
Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4, \
Tff7b72selfTff7b72.Td2a8ff_child_stderr Tff7b72= Te6edf3_launch_childTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_commandTb4b4b4, Te6edf3envTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_stdin_is_pipeTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_stdout_is_pipeTb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_stderr_is_pipeTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffStarted pid Tffd700{Tff7b72selfTff7b72.Td2a8ffpidTffd700}Ta5d6ff, fds: Tffd700{Tff7b72selfTff7b72.Td2a8ff_child_stdinTffd700}Ta5d6ff, Tffd700{Tff7b72selfTff7b72.Td2a8ff_child_stdoutTffd700}Ta5d6ff, Tffd700{Tff7b72selfTff7b72.Td2a8ff_child_stderrTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffpollTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3pidTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_return_code Tff7b72= Te6edf3osTff7b72.Td2a8ffwaitpidTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4, Te6edf3osTff7b72.Td2a8ffWNOHANGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_return_code Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_return_code Tff7b72= Tff7b72selfTff7b72.Td2a8ff_return_code Tff7b72& T79c0ff0xff
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_return_code Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tff7b72not Te6edf3process_existsTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_pidTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffpolled return code Tffd700{Tff7b72selfTff7b72.Td2a8ff_return_codeTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_terminated_cbTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_return_codeTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(Te6edf3CallbackSubprocessTff7b72.Td2a8ffPROCESS_POLL_TIMETb4b4b4, Te6edf3pollTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_ensure_pipes_closedTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3eTb4b4b4, Ta5d6ff"Ta5d6fferrnoTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3eTff7b72.Td2a8fferrno Tff7b72!= Te6edf3errnoTff7b72.Td2a8ffECHILDTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError in process poll: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(Te6edf3CallbackSubprocessTff7b72.Td2a8ffPROCESS_POLL_TIMETb4b4b4, Te6edf3pollTb4b4b4)

Tff7b72def Td2a8ffstdoutTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Te6edf3exceptionTff7b72.Td2a8ffpermitTb4b4b4(Tf85149SystemExitTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3tty_read_pollTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4)
Tff7b72if Te6edf3data Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stdout_cbTb4b4b4(Te6edf3dataTb4b4b4)
T8b949e# Opportunistically drain shortly after to coalesce immediate follow-up output
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffis_closedTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(T79c0ff0.01Tb4b4b4, Te6edf3stdoutTb4b4b4)
Tff7b72except Tf85149EOFErrorTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stdout_eof Tff7b72= Tff7b72True
Te6edf3tty_unset_reader_callbacksTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_stdout_cbTb4b4b4(Tffa657bytearrayTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffstderrTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Te6edf3exceptionTff7b72.Td2a8ffpermitTb4b4b4(Tf85149SystemExitTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3tty_read_pollTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stderrTb4b4b4)
Tff7b72if Te6edf3data Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stderr_cbTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffis_closedTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_loopTff7b72.Td2a8ffcall_laterTb4b4b4(T79c0ff0.01Tb4b4b4, Te6edf3stderrTb4b4b4)
Tff7b72except Tf85149EOFErrorTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stderr_eof Tff7b72= Tff7b72True
Te6edf3tty_unset_reader_callbacksTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stderrTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_stderr_cbTb4b4b4(Tffa657bytearrayTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3tty_add_reader_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4, Te6edf3stdoutTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_loopTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_child_stderr Tff7b72!= Tff7b72selfTff7b72.Td2a8ff_child_stdoutTb4b4b4:
Te6edf3tty_add_reader_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_child_stderrTb4b4b4, Te6edf3stderrTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_loopTb4b4b4)

Tf0883e@property
Tff7b72def Td2a8ffstdout_eofTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_stdout_eof Tff7b72or Tff7b72not Tff7b72selfTff7b72.Td2a8ffrunning

Tf0883e@property
Tff7b72def Td2a8ffstderr_eofTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_stderr_eof Tff7b72or Tff7b72not Tff7b72selfTff7b72.Td2a8ffrunning


Tf0883e@property
Tff7b72def Td2a8ffreturn_codeTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657intTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_return_code

Tf0883e@property
Tff7b72def Td2a8ffpidTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657intTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_pid


Tff7b72async Tff7b72def Td2a8ffmainTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""
A test driver for the CallbackProcess class.
python ./process.py /bin/zsh --login
"""

Tff7b72if Tffa657lenTb4b4b4(Te6edf3sysTff7b72.Td2a8ffargvTb4b4b4) Tff7b72<Tff7b72= T79c0ff1Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffUsage: Tffd700{Te6edf3sysTff7b72.Td2a8ffargvTffd700}Ta5d6ff <absolute_path_to_child_executable> [child_arg ...]Ta5d6ff"Tb4b4b4)
Te6edf3exitTb4b4b4(T79c0ff1Tb4b4b4)

Te6edf3loop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_event_loopTb4b4b4(Tb4b4b4)
T8b949e# asyncio.set_event_loop(loop)
Te6edf3retcode Tff7b72= Te6edf3loopTff7b72.Td2a8ffcreate_futureTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffstdoutTb4b4b4(Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4: Te6edf3osTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdoutTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dataTb4b4b4)

Tff7b72def Td2a8ffterminatedTb4b4b4(Te6edf3rcTb4b4b4: Tffa657intTb4b4b4)Tb4b4b4: Te6edf3retcodeTff7b72.Td2a8ffset_resultTb4b4b4(Te6edf3rcTb4b4b4)

Te6edf3process Tff7b72= Te6edf3CallbackSubprocessTb4b4b4(Te6edf3argvTff7b72=Te6edf3sysTff7b72.Td2a8ffargvTb4b4b4[T79c0ff1Tb4b4b4:Tb4b4b4]Tb4b4b4,
Te6edf3envTff7b72=Tb4b4b4{Ta5d6ff"Ta5d6ffTERMTa5d6ff"Tb4b4b4: Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffTERMTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffxtermTa5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4,
Te6edf3loopTff7b72=Te6edf3loopTb4b4b4,
Te6edf3stdout_callbackTff7b72=Te6edf3stdoutTb4b4b4,
Te6edf3terminated_callbackTff7b72=Te6edf3terminatedTb4b4b4)

Tff7b72def Td2a8ffsigint_handlerTb4b4b4(Te6edf3sigTb4b4b4, Te6edf3frameTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3process Tff7b72is Tff7b72None Tff7b72or Te6edf3processTff7b72.Td2a8ffstarted Tff7b72and Tff7b72not Te6edf3processTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72raise Tf85149KeyboardInterrupt
Tff7b72elif Te6edf3processTff7b72.Td2a8ffrunningTb4b4b4:
Te6edf3processTff7b72.Td2a8ffwriteTb4b4b4(Ta5d6ff"Tffea00\x03Ta5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffsigwinch_handlerTb4b4b4(Te6edf3sigTb4b4b4, Te6edf3frameTb4b4b4)Tb4b4b4:
Te6edf3processTff7b72.Td2a8ffcopy_winsizeTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3signalTff7b72.Td2a8ffsignalTb4b4b4(Te6edf3signalTff7b72.Td2a8ffSIGINTTb4b4b4, Te6edf3sigint_handlerTb4b4b4)
Te6edf3signalTff7b72.Td2a8ffsignalTb4b4b4(Te6edf3signalTff7b72.Td2a8ffSIGWINCHTb4b4b4, Te6edf3sigwinch_handlerTb4b4b4)

Tff7b72def Td2a8ffstdinTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Te6edf3tty_readTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3data Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3processTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3dataTb4b4b4)

Tff7b72except Tf85149EOFErrorTb4b4b4:
Te6edf3tty_unset_reader_callbacksTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3processTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3CTRL_DTb4b4b4)

Te6edf3tty_add_reader_callbackTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3stdinTb4b4b4)
Te6edf3processTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
T8b949e# call_soon called it too soon, not sure why.
Te6edf3loopTff7b72.Td2a8ffcall_laterTb4b4b4(T79c0ff0.001Tb4b4b4, Te6edf3functoolsTff7b72.Td2a8ffpartialTb4b4b4(Te6edf3processTff7b72.Td2a8ffcopy_winsizeTb4b4b4, Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)

Te6edf3val Tff7b72= Tff7b72await Te6edf3retcode
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffGot return code Tffd700{Te6edf3valTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Te6edf3val


Tff7b72if Tff7b72__name__ Tff7b72== Ta5d6ff"Ta5d6ff__main__Ta5d6ff"Tb4b4b4:
Te6edf3tr Tff7b72= Te6edf3TTYRestorerTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3trTff7b72.Td2a8ffrawTb4b4b4(Tb4b4b4)
Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4(Te6edf3mainTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72finallyTb4b4b4:
Te6edf3tty_unset_reader_callbacksTb4b4b4(Te6edf3sysTff7b72.Td2a8ffstdinTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3trTff7b72.Td2a8ffrestoreTb4b4b4(Tb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────